# 给你一个字符串表达式 s ，请你实现一个基本计算器来计算并返回它的值。 
# 
#  注意:不允许使用任何将字符串作为数学表达式计算的内置函数，比如 eval() 。 
# 
#  
# 
#  示例 1： 
# 
#  
# 输入：s = "1 + 1"
# 输出：2
#  
# 
#  示例 2： 
# 
#  
# 输入：s = " 2-1 + 2 "
# 输出：3
#  
# 
#  示例 3： 
# 
#  
# 输入：s = "(1+(4+5+2)-3)+(6+8)"
# 输出：23
#  
# 
#  
# 
#  提示： 
# 
#  
#  1 <= s.length <= 3 * 10⁵ 
#  s 由数字、'+'、'-'、'('、')'、和 ' ' 组成 
#  s 表示一个有效的表达式 
#  '+' 不能用作一元运算(例如， "+1" 和 "+(2 + 3)" 无效) 
#  '-' 可以用作一元运算(即 "-1" 和 "-(2 + 3)" 是有效的) 
#  输入中不存在两个连续的操作符 
#  每个数字和运行的计算将适合于一个有符号的 32位 整数 
#  
# 
#  Related Topics 栈 递归 数学 字符串 👍 1104 👎 0
import re
from operator import add, sub


# leetcode submit region begin(Prohibit modification and deletion)
class Solution:
    def calculate(self, s: str) -> int:
        stack = []
        # 1代表+。-1代表-
        symbol = 1
        cursum = 0

        i, n = 0, len(s)
        while i < n:
            c = s[i]
            if c.isdigit():
                num = 0
                # 这里是为了处理多位数，比如如果不做处理，可能一百就被读入为1，0，0三个数字而不是100
                while i < n and s[i].isdigit():
                    num = num * 10 + int(s[i])
                    i += 1
                # 这里为什么要i-1呢，因为就算不是多位数，单位数也满足while循环使得i+1多了1所以要减回去。若代码中使用s[i+1].isdigit()会导致数组越界。若代码中使用i < n-1会漏掉一位数字
                i -= 1
                # 这里为什么用*呢？因为我们把符号+定为了1，所以a*1 = a  a*-1 = -a,当然这里用if也行
                cursum += symbol * num
            elif c == "(":
                # 存储括号外的符号和sum，方便计算完括号内的和后计算
                stack.append(symbol)
                stack.append(cursum)
                # 重置为默认值，为什么要用这个默认值？因为+和0对于最终和没有影响，+a = a , a+0 = a
                symbol = 1
                cursum = 0
            elif c == ")":
                oldcursum = stack.pop()
                oldsymbol = stack.pop()
                # cursum += oldcursum * oldsymbol
                cursum = oldcursum + cursum * oldsymbol
            elif c == "+":
                symbol = 1

            elif c == "-":
                symbol = -1

            i += 1

        return cursum


# leetcode submit region end(Prohibit modification and deletion)
print(Solution().calculate(s="(1+(4+5+2)-3)+(6+8)"))
